/* Copyright (c) 2008, 2009, 2010, 2011 Damian Kmiecik
   All rights reserved.

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions are met:

   * Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
   * Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
     distribution.
   * Neither the name of the copyright holders nor the names of
     contributors may be used to endorse or promote products derived
     from this software without specific prior written permission.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  POSSIBILITY OF SUCH DAMAGE. */

#ifndef _ENC28J60REG_H
#define	_ENC28J60REG_H

#ifdef	__cplusplus
extern "C"
{
#endif

/**
 * Registers definitions
 */
	// Opcodes
#define ENC28J60_OPC_RCR			0x00
#define ENC28J60_OPC_RBM			0x3A
#define ENC28J60_OPC_WCR			0x40
#define ENC28J60_OPC_WBM			0x7A
#define ENC28J60_OPC_BFS			0x80
#define ENC28J60_OPC_BFC			0xA0
#define ENC28J60_OPC_SRC			0xFF
	// Banks
#define ENC28J60_BANK_MASK			0b01100000
#define ENC28J60_BANK_0				0b00000000
#define ENC28J60_BANK_1				0b00100000
#define ENC28J60_BANK_2				0b01000000
#define ENC28J60_BANK_3				0b01100000
	// PHY registers
#define ENC28J60_REG_PHCON1			0x00
#define ENC28J60_REG_PHSTAT1		0x01
#define ENC28J60_REG_PHID1			0x02
#define ENC28J60_REG_PHID2			0x03
#define ENC28J60_REG_PHCON2			0x10
#define ENC28J60_REG_PHSTAT2		0x11
#define ENC28J60_REG_PHIE			0x12
#define ENC28J60_REG_PHIR			0x13
#define ENC28J60_REG_PHLCON			0x14
	// Control registers
#define ENC28J60_REG_DUMMY_MASK		0b10000000
#define ENC28J60_REG_DUMMY			0b10000000
#define ENC28J60_REG_MASK			0b00011111
	// Registers in all banks
#define ENC28J60_REG_ECON1			0x1F
#define ENC28J60_REG_ECON2			0x1E
#define ENC28J60_REG_ESTAT			0x1D
#define ENC28J60_REG_EIR			0x1C
#define ENC28J60_REG_EIE			0x1B
	// Registers in bank 0
#define ENC28J60_REG_ERDPTL			0x00 | ENC28J60_BANK_0
#define ENC28J60_REG_ERDPTH			0x01 | ENC28J60_BANK_0
#define ENC28J60_REG_EWRPTL			0x02 | ENC28J60_BANK_0
#define ENC28J60_REG_EWRPTH			0x03 | ENC28J60_BANK_0
#define ENC28J60_REG_ETXSTL			0x04 | ENC28J60_BANK_0
#define ENC28J60_REG_ETXSTH			0x05 | ENC28J60_BANK_0
#define ENC28J60_REG_ETXNDL			0x06 | ENC28J60_BANK_0
#define ENC28J60_REG_ETXNDH			0x07 | ENC28J60_BANK_0
#define ENC28J60_REG_ERXSTL			0x08 | ENC28J60_BANK_0
#define ENC28J60_REG_ERXSTH			0x09 | ENC28J60_BANK_0
#define ENC28J60_REG_ERXNDL			0x0A | ENC28J60_BANK_0
#define ENC28J60_REG_ERXNDH			0x0B | ENC28J60_BANK_0
#define ENC28J60_REG_ERXRDPTL		0x0C | ENC28J60_BANK_0
#define ENC28J60_REG_ERXRDPTH		0x0D | ENC28J60_BANK_0
#define ENC28J60_REG_ERXWRPTL		0x0E | ENC28J60_BANK_0
#define ENC28J60_REG_ERXWRPTH		0x0F | ENC28J60_BANK_0
#define ENC28J60_REG_EDMASTL		0x10 | ENC28J60_BANK_0
#define ENC28J60_REG_EDMASTH		0x11 | ENC28J60_BANK_0
#define ENC28J60_REG_EDMANDL		0x12 | ENC28J60_BANK_0
#define ENC28J60_REG_EDMANDH		0x13 | ENC28J60_BANK_0
#define ENC28J60_REG_EDMADSTL		0x14 | ENC28J60_BANK_0
#define ENC28J60_REG_EDMADSTH		0x15 | ENC28J60_BANK_0
#define ENC28J60_REG_EDMACSL		0x16 | ENC28J60_BANK_0
#define ENC28J60_REG_EDMACSH		0x17 | ENC28J60_BANK_0
	// Registers in bank 1
#define ENC28J60_REG_ETH0			0x00 | ENC28J60_BANK_1
#define ENC28J60_REG_ETH1			0x01 | ENC28J60_BANK_1
#define ENC28J60_REG_ETH2			0x02 | ENC28J60_BANK_1
#define ENC28J60_REG_ETH3			0x03 | ENC28J60_BANK_1
#define ENC28J60_REG_ETH4			0x04 | ENC28J60_BANK_1
#define ENC28J60_REG_ETH5			0x05 | ENC28J60_BANK_1
#define ENC28J60_REG_ETH6			0x06 | ENC28J60_BANK_1
#define ENC28J60_REG_ETH7			0x07 | ENC28J60_BANK_1
#define ENC28J60_REG_EPMM0			0x08 | ENC28J60_BANK_1
#define ENC28J60_REG_EPMM1			0x09 | ENC28J60_BANK_1
#define ENC28J60_REG_EPMM2			0x0A | ENC28J60_BANK_1
#define ENC28J60_REG_EPMM3			0x0B | ENC28J60_BANK_1
#define ENC28J60_REG_EPMM4			0x0C | ENC28J60_BANK_1
#define ENC28J60_REG_EPMM5			0x0D | ENC28J60_BANK_1
#define ENC28J60_REG_EPMM6			0x0E | ENC28J60_BANK_1
#define ENC28J60_REG_EPMM7			0x0F | ENC28J60_BANK_1
#define ENC28J60_REG_EPMCSL			0x10 | ENC28J60_BANK_1
#define ENC28J60_REG_EPMCSH			0x11 | ENC28J60_BANK_1
#define ENC28J60_REG_EPMOL			0x14 | ENC28J60_BANK_1
#define ENC28J60_REG_EPMOH			0x15 | ENC28J60_BANK_1
#define ENC28J60_REG_ERXFCON		0x18 | ENC28J60_BANK_1
#define ENC28J60_REG_EPKTCNT		0x19 | ENC28J60_BANK_1
	// Registers in bank 2
#define ENC28J60_REG_MACON1			0x00 | ENC28J60_BANK_2 | ENC28J60_REG_DUMMY
#define ENC28J60_REG_MACON2			0x01 | ENC28J60_BANK_2 | ENC28J60_REG_DUMMY
#define ENC28J60_REG_MACON3			0x02 | ENC28J60_BANK_2 | ENC28J60_REG_DUMMY
#define ENC28J60_REG_MACON4			0x03 | ENC28J60_BANK_2 | ENC28J60_REG_DUMMY
#define ENC28J60_REG_MABBIPG		0x04 | ENC28J60_BANK_2 | ENC28J60_REG_DUMMY
#define ENC28J60_REG_MAIPGL			0x06 | ENC28J60_BANK_2 | ENC28J60_REG_DUMMY
#define ENC28J60_REG_MAIPGH			0x07 | ENC28J60_BANK_2 | ENC28J60_REG_DUMMY
#define ENC28J60_REG_MACLCON1		0x08 | ENC28J60_BANK_2 | ENC28J60_REG_DUMMY
#define ENC28J60_REG_MACLCON2		0x09 | ENC28J60_BANK_2 | ENC28J60_REG_DUMMY
#define ENC28J60_REG_MAMXFLL		0x0A | ENC28J60_BANK_2 | ENC28J60_REG_DUMMY
#define ENC28J60_REG_MAMXFLH		0x0B | ENC28J60_BANK_2 | ENC28J60_REG_DUMMY
#define ENC28J60_REG_MICMD			0x12 | ENC28J60_BANK_2 | ENC28J60_REG_DUMMY
#define ENC28J60_REG_MIREGADR		0x14 | ENC28J60_BANK_2 | ENC28J60_REG_DUMMY
#define ENC28J60_REG_MIWRL			0x16 | ENC28J60_BANK_2 | ENC28J60_REG_DUMMY
#define ENC28J60_REG_MIWRH			0x17 | ENC28J60_BANK_2 | ENC28J60_REG_DUMMY
#define ENC28J60_REG_MIRDL			0x18 | ENC28J60_BANK_2 | ENC28J60_REG_DUMMY
#define ENC28J60_REG_MIRDH			0x19 | ENC28J60_BANK_2 | ENC28J60_REG_DUMMY
	// Registers in bank 3
#define ENC28J60_REG_MAADR4			0x00 | ENC28J60_BANK_3 | ENC28J60_REG_DUMMY
#define ENC28J60_REG_MAADR5			0x01 | ENC28J60_BANK_3 | ENC28J60_REG_DUMMY
#define ENC28J60_REG_MAADR2			0x02 | ENC28J60_BANK_3 | ENC28J60_REG_DUMMY
#define ENC28J60_REG_MAADR3			0x03 | ENC28J60_BANK_3 | ENC28J60_REG_DUMMY
#define ENC28J60_REG_MAADR0			0x04 | ENC28J60_BANK_3 | ENC28J60_REG_DUMMY
#define ENC28J60_REG_MAADR1			0x05 | ENC28J60_BANK_3 | ENC28J60_REG_DUMMY
#define ENC28J60_REG_EBSTSD			0x06 | ENC28J60_BANK_3
#define ENC28J60_REG_EBSTCON		0x07 | ENC28J60_BANK_3
#define ENC28J60_REG_EBSTCSL		0x08 | ENC28J60_BANK_3
#define ENC28J60_REG_EBSTCSH		0x09 | ENC28J60_BANK_3
#define ENC28J60_REG_MISTAT			0x0A | ENC28J60_BANK_3 | ENC28J60_REG_DUMMY
#define ENC28J60_REG_EREVID			0x12 | ENC28J60_BANK_3
#define ENC28J60_REG_ECOCON			0x15 | ENC28J60_BANK_3
#define ENC28J60_REG_EFLOCON		0x17 | ENC28J60_BANK_3
#define ENC28J60_REG_EPAUSL			0x18 | ENC28J60_BANK_3
#define ENC28J60_REG_EPAUSH			0x19 | ENC28J60_BANK_3
	// Bits definitions
	// ECON1
#define ENC28J60_ECON1_BSEL0	    0x01
#define ENC28J60_ECON1_BSEL1	   	0x02
#define ENC28J60_ECON1_RXEN			0x04
#define ENC28J60_ECON1_TXRTS		0x08
#define ENC28J60_ECON1_CSUMEN		0x10
#define ENC28J60_ECON1_DMAST		0x20
#define ENC28J60_ECON1_RXRST		0x40
#define ENC28J60_ECON1_TXRST		0x80
	// ECON2
#define ENC28J60_ECON2_AUTOINC		0x80
#define ENC28J60_ECON2_PKTDEC		0x40
#define ENC28J60_ECON2_PWRSV		0x20
#define ENC28J60_ECON2_VRPS			0x08
	// MICMD
#define ENC28J60_MICMD_MIIRD	    0x01
#define ENC28J60_MICMD_MIISCAN	   	0x02
	// MISTAT
#define ENC28J60_MISTAT_BUSY		0x01
#define ENC28J60_MISTAT_SCAN		0x02
#define ENC28J60_MISTAT_NVALID		0x04
	// MACON1
#define ENC28J60_MACON1_MARXEN		0x01
#define ENC28J60_MACON1_PASSALL		0x02
#define ENC28J60_MACON1_RXPAUS		0x04
#define ENC28J60_MACON1_TXPAUS		0x08
	// MACON3
#define ENC28J60_MACON3_FULDPX		0x01
#define ENC28J60_MACON3_FRMLNEN		0x02
#define ENC28J60_MACON3_HFRMEN		0x04
#define ENC28J60_MACON3_PHDREN		0x08
#define ENC28J60_MACON3_TXCRCEN		0x10
#define ENC28J60_MACON3_PADCFG0		0x20
#define ENC28J60_MACON3_PADCFG1		0x40
#define ENC28J60_MACON3_PADCFG2		0x80
	// MACON4
#define ENC28J60_MACON4_NOBKOFF		0x10
#define ENC28J60_MACON4_BPEN		0x20
#define ENC28J60_MACON4_DEFER		0x40
	// MABBIPG
#define ENC28J60_MABBIPG_BBIPG0		0x01
#define ENC28J60_MABBIPG_BBIPG1		0x02
#define ENC28J60_MABBIPG_BBIPG2		0x04
#define ENC28J60_MABBIPG_BBIPG3		0x08
#define ENC28J60_MABBIPG_BBIPG4		0x10
#define ENC28J60_MABBIPG_BBIPG5		0x20
#define ENC28J60_MABBIPG_BBIPG6		0x40
	// ERXFCON
#define ENC28J60_ERXFCON_UCEN		0x80
#define ENC28J60_ERXFCON_ANDOR		0x40
#define ENC28J60_ERXFCON_CRCEN		0x20
#define ENC28J60_ERXFCON_PMEN		0x10
#define ENC28J60_ERXFCON_MPEN		0x08
#define ENC28J60_ERXFCON_HTEN		0x04
#define ENC28J60_ERXFCON_MCEN		0x02
#define ENC28J60_ERXFCON_BCEN		0x01
	// EIE
#define ENC28J60_EIE_INTIE			0x80
#define ENC28J60_EIE_PKTIE			0x40
#define ENC28J60_EIE_DMAIE	    	0x20
#define ENC28J60_EIE_LINKIE	    	0x10
#define ENC28J60_EIE_TXIE	    	0x08
#define ENC28J60_EIE_WOLIE	    	0x04
#define ENC28J60_EIE_TXERIE			0x02
#define ENC28J60_EIE_RXERIE	    	0x01
	// EIR
#define ENC28J60_EIR_PKTIF			0x40
#define ENC28J60_EIR_DMAIF			0x20
#define ENC28J60_EIR_LINKIF	    	0x10
#define ENC28J60_EIR_TXIF			0x08
#define ENC28J60_EIR_WOLIF			0x04
#define ENC28J60_EIR_TXERIF			0x02
#define ENC28J60_EIR_RXERIF			0x01
	// ESTAT
#define ENC28J60_ESTAT_INT			0x80
#define ENC28J60_ESTAT_LATECOL		0x10
#define ENC28J60_ESTAT_RXBUSY		0x04
#define ENC28J60_ESTAT_TXABRT		0x02
#define ENC28J60_ESTAT_CLKRDY		0x01
	// PHCON1
#define ENC28J60_PHCON1_PRST		0x8000
#define ENC28J60_PHCON1_PLOOPBK		0x4000
#define ENC28J60_PHCON1_PPWRSV		0x0800
#define ENC28J60_PHCON1_PDPXMD		0x0100
	// PHSTAT1
#define ENC28J60_PHSTAT1_PFDPX		0x1000
#define ENC28J60_PHSTAT1_PHDPX		0x0800
#define ENC28J60_PHSTAT1_LLSTAT		0x0004
#define ENC28J60_PHSTAT1_JBSTAT		0x0002
	// PHCON2
#define ENC28J60_PHCON2_HDLDIS		0x0100
#define ENC28J60_PHCON2_JABBER		0x0400
#define ENC28J60_PHCON2_TXDIS		0x2000
#define ENC28J60_PHCON2_FRCLNK		0x4000
	// Packet Control Byte
#define ENC28J60_PKTCTRL_PHUGEEN	0x08
#define ENC28J60_PKTCTRL_PPADEN		0x04
#define ENC28J60_PKTCTRL_PCRCEN		0x02
#define ENC28J60_PKTCTRL_POVERRIDE	0x01
	// ECOCON clock settings
#define ENC28J60_ECOCON_DISABLE		0x00
#define ENC28J60_ECOCON_3_125_MHz	0x05
#define ENC28J60_ECOCON_6_25_MHz	0x04
#define ENC28J60_ECOCON_8_333_MHz	0x03
#define ENC28J60_ECOCON_12_5_MHz	0x02
#define ENC28J60_ECOCON_25_MHz		0x01
	// Recive status vector
#define ENC28J60_RSV_RECIVED_OK		0x0080
#define ENC28J60_RSV_CRC_ERROR		0x0010
#define ENC28J60_RSV_BROADCAST		0x0200
#define ENC28J60_RSV_MULTICAST		0x0100

#ifdef	__cplusplus
}
#endif

#endif	/* _ENC28J60REG_H */
